package handler

import (
	"context"
	"crypto/sha512"
	"errors"
	"fmt"
	password "github.com/anaskhan96/go-password-encoder"
	"go.uber.org/zap"
	"strings"
	"user_srv/global"
	"user_srv/model"

	proto "user_srv/proto"
)

type User_srv struct{}

// GetUserList 查询用户列表
func (h *User_srv) GetUserList(ctx context.Context, req *proto.RequestLimitList, rep *proto.ResponseUserList) error {
	var users []model.User
	zap.S().Debug("原始结构", users)
	//获取总数
	result := global.DB.Find(&users)
	if result.Error != nil {
		return result.Error
	}
	rep.Total = int32(result.RowsAffected)
	rep.Page = int32(req.Page)
	rep.Limit = int32(req.Limit)

	zap.S().Debug("全量数据", users)

	//获取查询条数

	if req.Page > 0 && req.Limit > 0 {
		global.DB.Scopes(model.Paginate(int(req.Page), int(req.Limit))).Find(&users)
	}
	for _, role := range users {
		Datas := &proto.ResponseUserInfo{}
		err := global.SwapTo(role, Datas)
		Datas.PassWord = ""
		if err != nil {
			return err
		}
		rep.List = append(rep.List, Datas)
	}
	return nil
}

// AddUser 添加用户
func (h *User_srv) AddUser(ctx context.Context, req *proto.RequestUserInfo, rep *proto.Response) error {
	user := &model.User{}
	Db := global.DB

	userData := Db.First(user, req.Account)
	if userData.RowsAffected == 1 {
		zap.S().Errorf("用户名为 [ %s ] 的用户已存在", req.Account)
		return userData.Error
	}
	roleData := Db.Where("id", req.Role).First(&model.Role{})
	if roleData.RowsAffected == 0 {
		zap.S().Errorf("ID为 [ %s ] 的用户已存在", req.Role)
		return userData.Error
	}
	//匹配数据
	if err := global.SwapTo(req, user); err != nil {
		return err
	}

	//密码加密
	if req.PassWord != "" {
		user.Password = chkPassword(req.PassWord)
	}

	zap.S().Debug("添加用户接取参数", user)

	//开启事物
	startDo := Db.Begin()
	//创建用户
	result := startDo.Create(user)

	if result.Error != nil {
		//事物回滚
		startDo.Rollback()
		return result.Error
	}
	//获取创建的用户ID
	startDo.Commit()
	return nil
}

// GetUserInfoByUserid 根据id查询用户信息
func (h *User_srv) GetUserInfoByUserid(ctx context.Context, req *proto.RequestUserId, rep *proto.ResponseUserInfo) error {
	var user model.User
	//查询用户信息
	if err := global.DB.First(&user, req.Userid); err.Error != nil {
		return err.Error
	}
	if err := global.SwapTo(user, rep); err != nil {
		return err
	}
	//获取用户权限信息
	getUserAuth(user.ID, user.Role, rep)
	zap.S().Debug("返回信息", rep)
	return nil
}

//获取用户权限信息
func getUserAuth(userId int64, roleId int64, rep *proto.ResponseUserInfo) error {
	var RoleUserAuth []model.RoleUserAuth
	//result := make([]interface{}, 0)
	//根据角色查询用户权限信息
	if err := global.DB.Where("type", 1).Where("role_id", roleId).Find(&RoleUserAuth); err.Error != nil {
		return err.Error
	}
	for _, RoleUserAuth := range RoleUserAuth {
		Datas := &proto.ResponseRoleUserAuth{}
		if err := global.SwapTo(RoleUserAuth, Datas); err != nil {
			return err
		}
		rep.Authlist = append(rep.Authlist, Datas)
	}

	//根据用户ID查询权限信息
	if err := global.DB.Where("type", 2).Where("role_id", roleId).Find(&RoleUserAuth); err.Error != nil {
		return err.Error
	}
	for _, RoleUserAuth := range RoleUserAuth {
		Datas := &proto.ResponseRoleUserAuth{}
		if err := global.SwapTo(RoleUserAuth, Datas); err != nil {
			return err
		}
		rep.Authlist = append(rep.Authlist, Datas)
	}
	return nil
}

// GetUserInfoByAccount 根据账号查询用户信息
func (h *User_srv) GetUserInfoByAccount(ctx context.Context, req *proto.RequestAccount, rep *proto.ResponseUserInfo) error {
	var user model.User
	result := global.DB.Where("account", req.Account).First(&user)

	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("无有效用户")
	}

	if err := global.SwapTo(user, rep); err != nil {
		return err
	}

	//获取用户权限信息
	getUserAuth(user.ID, user.Role, rep)
	return nil
}

func (h *User_srv) GetUserInfoByName(ctx context.Context, req *proto.RequestName, rep *proto.ResponseUserInfo) error {
	var user model.User
	zap.S().Debug("根据姓名查询用户信息条件", req)
	//查询用户信息
	if err := global.DB.Where("user_name", req.UserName).Find(&user); err.Error != nil || err.RowsAffected == 0 {
		if err.RowsAffected == 0 {
			return errors.New("无有效用户")
		} else {
			return err.Error
		}
	}
	zap.S().Debug("根据姓名查询用户信息结果", user)

	if err := global.SwapTo(user, rep); err != nil {
		return err
	}
	//获取用户权限信息
	getUserAuth(user.ID, user.Role, rep)

	return nil
}

func (h *User_srv) GetUserInfoByMobile(ctx context.Context, req *proto.RequestMobile, rep *proto.ResponseUserInfo) error {
	var user model.User
	zap.S().Debug("根据电话查询用户信息条件", &req)

	//查询用户信息
	if err := global.DB.Where("mobile", req.Mobile).Find(&user); err.Error != nil || err.RowsAffected == 0 {
		if err.RowsAffected == 0 {
			return errors.New("无有效用户")
		} else {
			return err.Error
		}
	}

	zap.S().Debug("根据电话查询用户信息结果", &user)

	if err := global.SwapTo(&user, rep); err != nil {
		return err
	}

	//获取用户权限信息
	getUserAuth(user.ID, user.Role, rep)
	return nil
}

// DelUser 删除用户信息
func (h *User_srv) DelUser(ctx context.Context, req *proto.RequestUserId, rep *proto.Response) error {
	user := &model.User{}
	userData := global.DB.First(user, req.Userid)
	if userData.RowsAffected == 0 {
		return errors.New("无有效用户")
	}
	result := global.DB.Delete(user)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// EditUser 编辑用户信息
func (h *User_srv) EditUser(ctx context.Context, req *proto.RequestUserInfo, rep *proto.Response) error {
	user := model.User{}
	//var arrRoleUserAuths map[int64]interface{}

	db := global.DB

	//获取用户信息
	if userData := db.First(&user, req.Id); userData.RowsAffected == 0 {
		return errors.New("用户不存在")
	}
	zap.S().Debug("用户信息", user)

	upData := make(map[string]interface{}, 5)

	if req.Status != 0 && req.Status != user.Status {
		upData["status"] = req.Status
	}

	if req.Role != 0 && req.Role != user.Role {
		upData["role"] = req.Role
	}

	if req.Departments != "" && req.Departments != user.Departments {
		upData["departments"] = req.Departments
	}

	//if req.PassWord != "" && chkPassword(req.Departments) != user.Password {
	//	upData["PassWord"] = req.PassWord
	//}
	if req.Mobile != "" && req.Mobile != user.Mobile {
		upData["mobile"] = req.Mobile
	}
	if req.Email != "" && req.Email != user.Email {
		upData["email"] = req.Email
	}

	if req.Addr != "" && req.Addr != user.Addr {
		upData["addr"] = req.Addr
	}
	if err := db.Model(&model.User{}).Where("id", user.ID).Updates(upData); err.Error != nil {
		return err.Error
	}
	//开启事物
	//startDo := db.Begin()
	//回滚信息
	//startDo.Rollback()
	//提交信息
	//startDo.Commit()
	return nil
}

//获取密码
func chkPassword(pass string) string {
	options := &password.Options{16, 100, 32, sha512.New}
	salt, encodedPwd := password.Encode(pass, options)
	pass = fmt.Sprintf("$pbkdf2-sha512$%s$%s", salt, encodedPwd)
	return pass
}

//校验密码
func (h *User_srv) GetPassword(ctx context.Context, req *proto.RequestPassword, rep *proto.ResponsePassword) error {
	options := &password.Options{16, 100, 32, sha512.New}
	passwordInfo := strings.Split(req.EncryptedPassword, "$")
	rep.Code = password.Verify(req.Password, passwordInfo[2], passwordInfo[3], options)
	return nil
}
